package main

import (
	"log"
	"math/rand"
	"runtime"
)

func main() {

	chanintA_main()
}

//利用关闭chan后，可以从chan中获取零值的 思想，停止关闭零一个chan，从而停止生产随机int数据
func chanintA_main() {
	strChan := make(chan int64)
	ch := chanintA(strChan)
	log.Printf("receive =%+v \n", <-ch)
	log.Printf("receive =%+v \n", <-ch)
	log.Printf("receive =%+v \n", <-ch)
	close(strChan)
	log.Printf("receive =%+v \n", <-ch)
	log.Printf("receive =%+v \n", <-ch)
}

//该方法中 利用for 和select 的组合生产随机的int数
//利用从管道中取数据的方式 跳出for循环
func chanintA(done chan int64) chan int {
	ch := make(chan int)
	go func() {
	tmp:
		for {
			select {
			case ch <- rand.Int():
			case i := <-done:
				log.Printf("stop =%s \n", i)
				break tmp
			}
		}
		close(ch)
	}()
	return ch
}

//实现了死循环 输出0、1
func test03() {
	ch := make(chan int, 1)
	go func(chan int) {
		for {
			select {
			case ch <- 0:
			case ch <- 1:
			}
		}
	}(ch)
	//这样死循环输出 0、1
	for v := range ch {
		log.Printf("%+v", v)
	}
}

//先给长chan 中存放数据，之后关闭chan 后，在将该chan中的数据取出来
func test02() {
	c := make(chan struct{})
	ci := make(chan int, 100)
	go func(chan struct{}, chan int) {
		for i := 1; i < 10; i++ {
			ci <- i
		}
		close(ci)
		c <- struct{}{}
	}(c, ci)
	println("1:=", runtime.NumGoroutine())
	<-c
	println("2:=", runtime.NumGoroutine())
	for v := range ci {
		log.Println(v)
	}
	println("3:=", runtime.NumGoroutine())
}
func test01() {
	c := make(chan struct{})
	go func(c chan struct{}) {
		sum := 0
		for i := 0; i < 1000; i++ {
			sum += i
		}
		log.Println(sum)
		c <- struct{}{}

	}(c)

	log.Println(runtime.NumGoroutine())
	<-c
}
